/*
 * Ressource.h
 *
 *  Created on: 15 oct. 2010
 *      Author: seeme
 *
 *      Based on the article in GamePrograming Gem 3..
 *      Une ressource a une priorité, est sérializable
 *      elle en peut être delete que par le cache mémoire.
 *      De plus, elle agit comme un smart pointer.
 *      Si le ompteur de référence est > 0 => qqun utilise le pointeur,
 *      on ne peut donc pas le delete (sauf quit de l'application)
 */

#ifndef RESSOURCE_H_
#define RESSOURCE_H_
#include <cstddef>
#include <ctime>
#include <iostream>
#include "../../LogManager/Log.hpp"

class Resource {

	friend class ResCache;

public:
	enum PriorityType{
		RES_LOW_PRIORITY = 0,
		RES_MED_PRIORITY,
		RES_HIGH_PRIORITY
	};

	Resource(){clear();}

	virtual void clear();

	//Erase all data
	virtual bool create() = 0;
	virtual void destroy(){};
	virtual size_t getSize() = 0;

	inline void setPriority(PriorityType priority){ m_priority = priority; }
	inline PriorityType getPriority(){ return m_priority; }

	inline void upRefCount(){m_refCount += 1;}
	inline void downRefCount(){
		if(m_refCount > 0){
			m_refCount --;
		}else{
			//ERROR
		}
	}

	inline void setReferenceCount(unsigned int count){ m_refCount = count; }
	inline unsigned int getReferenceCount(){ return m_refCount; }

	virtual bool operator < (Resource& container);

	Resource(std::string name, std::string path):m_name(name), m_filePath(path){ clear(); }
	std::string getFilePath(){return m_filePath;}

protected:
	std::string m_name;
	std::string m_filePath;
	virtual ~Resource(){destroy();};

private:
	PriorityType m_priority;
	unsigned int m_refCount;
	time_t m_lastAccess;

protected:
	unsigned int m_size;
};

// This class allows an STL object to compare the objects instead of
// comparing the value of the objects' pointers.
template <class T>
class ptr_less
{
public:
	inline bool operator ()(T left, T right)
	{  return ((*left) < (*right));  }
};

// This class allows an STL object to compare the objects instead of
// comparing the value of the objects' pointers.
template <class T>
class ptr_greater
{
public:
	inline bool operator ()(T left, T right)
	{  return !((*left) < (*right));  }
};

#endif /* RESSOURCE_H_ */
